package ast


type VariousStatement struct {
	Node                   `part:"stmt"`
	Statement  Statement   `use:"first"`
}
type Statement interface { impl(Statement) }

func (DeclEntry) impl(Statement) {}
type DeclEntry struct {
	Node            `part:"decl_entry"`
	Content  Block  `part:"block"`
}

func (DeclType) impl(Statement) {}
type DeclType struct {
	Node                         `part:"decl_type"`
	Docs        [] Doc           `list:"docs.doc+"`
	Name        Identifier       `part:"name"`
	TypeParams  [] Identifier    `list:"type_params.name*,"`
	Implements  [] RefBase       `list:"impl.ref_base*,"`
	TypeDef     VariousTypeDef   `part:"type_def"`
}

func (DeclOperator) impl(Statement) {}
type DeclOperator struct {
	Node                           `part:"decl_op"`
	Docs       [] Doc              `list:"docs.doc+"`
	Public     bool                `option:"public.@public"`
	Infix      bool                `option:"infix.@infix"`
	Variadic   bool                `option:"variadic.@variadic"`
	Name       Identifier          `part:"name"`
	Signature  OperatorSignature   `part:"sig"`
	Body       VariousBody         `part:"body"`
}
type OperatorSignature struct {
	Node                        `part:"sig"`
	TypeParams  [] Identifier   `list:"type_params.name*,"`
	Inputs      Inputs          `part:"inputs"`
	Implicit    MaybeInputs     `part_opt:"implicit.inputs"`
	Output      Type            `part:"output.type"`
}
type MaybeInputs interface { impl(MaybeInputs) }
func (Inputs) impl(MaybeInputs) {}
type Inputs struct {
	Node                 `part:"inputs"`
	Content  RecordDef   `part:"record_def"`
}
type VariousBody struct {
	Node         `part:"body"`
	Body  Body   `use:"first"`
}
type Body interface { implBody() }
func (NativeBody) implBody() {}
type NativeBody struct {
	Node         `part:"native_body"`
	Id    Text   `part:"text"`
}

func (DeclMethod) impl(Statement) {}
type DeclMethod struct {
	Node                    `part:"decl_method"`
	Docs      [] Doc        `list:"docs.doc+"`
	Public    bool          `option:"public.@public"`
	Receiver  Identifier    `part:"receiver.name"`
	Name      Identifier    `part:"name"`
	Type      Type          `part:"type"`
	Body      VariousBody   `part:"body"`
}

func (DeclConst) impl(Statement) {}
type DeclConst struct {
	Node                    `part:"decl_const"`
	Docs      [] Doc        `list:"docs.doc+"`
	Public    bool          `option:"public.@public"`
	Name      Identifier    `part:"name"`
	Type      Type          `part:"type"`
	Value     VariousBody   `part:"body"`
}

func (DeclMessage) impl(Statement) {}
type DeclMessage struct {
	Node                      `part:"decl_msg"`
	Docs     [] Doc           `list:"docs.doc+"`
	Public   bool             `option:"public.@public"`
	Lang     Identifier       `part:"msg_lang.name"`
	Name     Identifier       `part:"name"`
	Inputs   Inputs           `part:"inputs"`
	Content  VariousMsgExpr   `part:"msg_expr"`
}
type VariousMsgExpr struct {
	Node               `part:"msg_expr"`
	MsgExpr  MsgExpr   `use:"first"`
}
type MsgExpr interface { implMsgExpr() }
func (MsgExprPlain) implMsgExpr() {}
type MsgExprPlain struct {
	Node                     `part:"msg_expr_plain"`
	Content  StringLiteral   `part:"string"`
}
func (MsgExprSingularPlural) implMsgExpr() {}
type MsgExprSingularPlural struct {
	Node                             `part:"msg_expr_sp"`
	SingularContent  StringLiteral   `part:"msg_singular.string"`
	PluralContent    StringLiteral   `part:"msg_plural.string"`
}

type Doc struct {
	Node                  `part:"doc"`
	RawContent  [] rune   `content:"Doc"`
}


